﻿using System;
using System.Collections.Generic;
using System.Text;

using System.Diagnostics.Contracts;

using SimpleIR;

namespace RgnAnalyzer.Domain
{
	public partial class AProgramMemory
	{
		internal void SimulateBuiltinCall(IRBodyDef bd, int line, bool conscall)
		{
			Contract.Requires(!this.IsInfeasable);
			Contract.Requires(bd != null);

			String mns = bd.BuiltinSemanticName;
			IRType thisTy = bd.InvokeID.DefInClass; //for use on member methods

			int argc = (bd.InvokeID.Sig.IsVirtualInvoke ? (bd.InvokeID.Sig.InvokeSig.Count + 1) : bd.InvokeID.Sig.InvokeSig.Count);
			int baseoffset = this.m_evalstack.Count - argc;

			if(mns.Equals("object_init"))
			{
				this.EvalStackPop();
			}
			else if(mns.Equals("string_from_chars_rng"))
			{
				AEvalStackEntry sse = this.m_evalstack[baseoffset];

				this.EvalStackPop();
				this.EvalStackPop();
				IRContainerType caty = (IRContainerType)((IRPtrType)this.EvalStackPeek().SLocType).PtrTargetType;
				this.SimulateIndexAddrByField(caty.ContentsField, 0);
				this.SimulateDeRefIndirectRead(line);

				this.SimulateIndexAddrByField(GlobalAnalysisState.TProg.TypeTable.StringObjectType.TypeDescription.GetFieldWithNameDefIn("sval"), 1); 
				this.SimulateDeRefIndirectWrite(line);

				if(conscall)
					this.EvalStackPush(sse);
			}
			else if(mns.Equals("list_alloc_default"))
			{
				if(!conscall)
					this.EvalStackPop();
			}
			else if(mns.Equals("hashset_init"))
			{
				if(!conscall)
					this.EvalStackPop();
			}
			else if(mns.Equals("init_keyvalpair"))
			{
				this.BISimulateCons_KeyValuePair(thisTy, line);
			}
			else if(mns.Equals("dictionary_init"))
			{
				if(!conscall)
					this.EvalStackPop();
			}
			else if(mns.Equals("stringbuilder_alloc"))
			{
				if(!conscall)
					this.EvalStackPop();
			}
			else if(mns.Equals("filestream_init"))
			{
				if(!this.BICheckPtrArgNonNull(baseoffset + 1))
					this.SetInfeasable();
				else
				{
					this.BIReadStringData(baseoffset + 1, line);
					this.BIHavocExternalState(line);
					this.ReturnFromBuiltinClearTopKArgs(argc);
				}
			}
			else if(mns.Equals("nop"))
			{
				this.ReturnFromBuiltinClearTopKArgs(argc);
			}
			else if(mns.Equals("object_equals"))
			{
				this.SimulateDrefableEQ();
			}
			else if(mns.Equals("object_hashcode"))
			{
				AObject oo = this.BILoadUniqueEvalPtr(baseoffset);
				oo.MarkRTTIUsed(line);
				this.EvalStackPop();
				this.EvalStackPush(GlobalAnalysisState.TProg.TypeTable.Int64Type, ZeroOne.Value.Unknown);
			}
			else if(mns.Equals("object_equals_staticbyref"))
			{
				this.SimulateDrefableEQ();
			}
			else if(mns.Equals("object_hashcode_static"))
			{
				APtrValueMap pa = this.EvalStackPopWVal().PointerValue;
				for(int i = 0; i < pa.PTargetCount; ++i)
				{
					AObject ploc = this.ResolvePointerTarget(pa.PTargets[i]);
					ploc.MarkRTTIUsed(line);
				}
				this.EvalStackPush(GlobalAnalysisState.TProg.TypeTable.Int64Type, ZeroOne.Value.Unknown);
			}
			else if(mns.Equals("memberwise_copy"))
			{
				AObject origobj = this.BILoadUniqueEvalPtr(baseoffset);
				AObject newloc = origobj.SimulateObjectClone(this.m_memory, line);
				APossiblePointerTarget ppt = new APossiblePointerTarget(newloc.Address);
				this.EvalStackPop();
				this.EvalStackPush(GlobalAnalysisState.TProg.TypeTable.LookupPointerTypeFor((IRClassType)newloc.LocationType), ppt, true);
			}
			else if(mns.Equals("internal_string_compare"))
			{
				this.BIReadStringData(baseoffset, line);
				this.BIReadStringData(baseoffset + 2, line);
				this.ReturnFromBuiltinClearTopKArgs(argc);
				this.EvalStackPush(GlobalAnalysisState.TProg.TypeTable.Int64Type, ZeroOne.Value.Unknown);
			}
			else if(mns.Equals("ceiling_double") || mns.Equals("floor_double") || mns.Equals("log_double") || mns.Equals("sqrt_double"))
			{
				this.SimulateUninterpUnary();
			}
			else if(mns.Equals("pow_double"))
			{
				this.SimulateUninterpBin();
			}
			else if(mns.Equals("sin_double") || mns.Equals("cos_double") || mns.Equals("tan_double"))
			{
				this.SimulateUninterpUnary();
			}
			else if(mns.Equals("exit_program"))
			{
				this.SetInfeasable();
			}
			else if(mns.Equals("concat_string_array"))
			{
				IRClassType strty = GlobalAnalysisState.TProg.TypeTable.StringObjectType;
				IRPtrType spt = GlobalAnalysisState.TProg.TypeTable.LookupPointerTypeFor(strty);

				this.EvalStackPush(GlobalAnalysisState.TProg.TypeTable.Int64Type, ZeroOne.Value.Unknown);
				this.SimulateArrayLoad(line, spt);
				this.BIReadStringData(this.m_evalstack.Count - 1, line);
				this.EvalStackPop();
				this.SimulatePushString(line);
			}
			else if(mns.Equals("get_string_length"))
			{
				IRMemberField slf = GlobalAnalysisState.TProg.TypeTable.StringObjectType.TypeDescription.GetFieldWithNameDefIn("slen");
				this.SimulateIndexAddrByField(slf, 0);
				this.SimulateDeRefIndirectRead(line);
				this.EvalStackPop();
				this.EvalStackPush(GlobalAnalysisState.TProg.TypeTable.Int64Type, ZeroOne.Value.Unknown);
			}
			else if(mns.Equals("get_string_char"))
			{
				this.EvalStackPop();
				this.SimulateDup();

				IRMemberField slf = GlobalAnalysisState.TProg.TypeTable.StringObjectType.TypeDescription.GetFieldWithNameDefIn("slen");
				this.SimulateIndexAddrByField(slf, 0);
				this.SimulateDeRefIndirectRead(line);

				IRMemberField svf = GlobalAnalysisState.TProg.TypeTable.StringObjectType.TypeDescription.GetFieldWithNameDefIn("sval");
				this.SimulateIndexAddrByField(svf, 0);
				this.SimulateDeRefIndirectRead(line);
			}
			else if(mns.Equals("internal_string_formatbuild"))
			{
				if(!this.BICheckPtrArgNonNull(baseoffset + 1))
					this.SetInfeasable();
				else
				{
					IRClassType strty = GlobalAnalysisState.TProg.TypeTable.StringObjectType;
					IRPtrType spt = GlobalAnalysisState.TProg.TypeTable.LookupPointerTypeFor(strty);

					this.EvalStackPush(GlobalAnalysisState.TProg.TypeTable.Int64Type, ZeroOne.Value.Unknown);
					this.SimulateArrayLoad(line, spt);
					this.BIReadStringData(this.m_evalstack.Count - 1, line);
					this.BIReadStringData(baseoffset + 1, line);
					this.ReturnFromBuiltinClearTopKArgs(2);
					this.SimulatePushString(line);
				}
			}
			else if(mns.Equals("bool_get_truth"))
			{
				this.EvalStackPop();
				this.EvalStackPush(GlobalAnalysisState.TProg.TypeTable.BoolType, ZeroOne.Value.Unknown);
			}
			else if(mns.Equals("char_is_whitepace"))
			{
				this.EvalStackPop();
				this.EvalStackPush(GlobalAnalysisState.TProg.TypeTable.BoolType, ZeroOne.Value.Unknown);
			}
			else if(mns.Equals("parse_as_integral"))
			{
				if(!this.BICheckPtrArgNonNull(baseoffset))
					this.SetInfeasable();
				else
				{
					this.BIReadStringData(baseoffset, line);
					this.ReturnFromBuiltinClearTopKArgs(argc);
					this.EvalStackPush(GlobalAnalysisState.TProg.TypeTable.Int64Type, ZeroOne.Value.Unknown);
				}
			}
			else if(mns.Equals("parse_as_usignintegral"))
			{
				if(!this.BICheckPtrArgNonNull(baseoffset))
					this.SetInfeasable();
				else
				{
					this.BIReadStringData(baseoffset, line);
					this.ReturnFromBuiltinClearTopKArgs(argc);
					this.EvalStackPush(GlobalAnalysisState.TProg.TypeTable.UInt64Type, ZeroOne.Value.Unknown);
				}
			}
			else if(mns.Equals("parse_as_floatingpoint"))
			{
				if(!this.BICheckPtrArgNonNull(baseoffset))
					this.SetInfeasable();
				else
				{
					this.BIReadStringData(baseoffset, line);
					this.ReturnFromBuiltinClearTopKArgs(argc);
					this.EvalStackPush(GlobalAnalysisState.TProg.TypeTable.Float64Type, ZeroOne.Value.Unknown);
				}
			}
			else if(mns.Equals("format_integral_as_string") || mns.Equals("format_usignintegral_as_string") || mns.Equals("format_floatingpoint_as_string"))
			{
				this.EvalStackPop();
				this.SimulatePushString(line);
			}
			else if(mns.Equals("get_string_hashcode"))
			{
				this.BIReadStringData(baseoffset, line);
				this.EvalStackPop();
				this.EvalStackPush(GlobalAnalysisState.TProg.TypeTable.Int64Type, ZeroOne.Value.Unknown);
			}
			else if(mns.Equals("string_replace"))
			{
				if((!this.BICheckPtrArgNonNull(baseoffset)) || (!this.BICheckPtrArgNonNull(baseoffset + 1)))
					this.SetInfeasable();
				else
				{
					this.BIReadStringData(baseoffset, line);
					this.BIReadStringData(baseoffset + 1, line);
					this.ReturnFromBuiltinClearTopKArgs(argc);
					this.SimulatePushString(line);
				}
			}
			else if(mns.Equals("string_indexof_string"))
			{
				if(!this.BICheckPtrArgNonNull(baseoffset + 1))
					this.SetInfeasable();
				else
				{
					this.BIReadStringData(baseoffset, line);
					this.BIReadStringData(baseoffset + 1, line);
					this.ReturnFromBuiltinClearTopKArgs(argc);
					this.EvalStackPush(GlobalAnalysisState.TProg.TypeTable.Int64Type, ZeroOne.Value.Unknown);
				}
			}
			else if(mns.Equals("string_split"))
			{
				if(!this.BICheckPtrArgNonNull(baseoffset))
					this.SetInfeasable();
				else
				{
					this.EvalStackPush(GlobalAnalysisState.TProg.TypeTable.Int64Type, ZeroOne.Value.Unknown);
					this.SimulateArrayLoad(line, GlobalAnalysisState.TProg.TypeTable.CharType);
					this.BIReadStringData(baseoffset, line);

					this.AllocateStringArray(line);
				}
			}
			else if(mns.Equals("string_trim"))
			{
				this.BIReadStringData(baseoffset, line);
				this.ReturnFromBuiltinClearTopKArgs(argc);
				this.SimulatePushString(line);
			}
			else if(mns.Equals("havoc_externalstate"))
			{
				this.BIHavocExternalState(line);
			}
			else if(mns.Equals("array_sort_on"))
			{
				throw new NotImplementedException();
			}
			else if(mns.Equals("list_add"))
			{
				this.BIAddToList(baseoffset, line, (IRContainerType)thisTy);
			}
			else if(mns.Equals("list_clear"))
			{
				this.BIClearList(baseoffset, line, (IRContainerType)thisTy);
			}
			else if(mns.Equals("list_insert_index"))
			{
				AEvalStackEntry evse = this.EvalStackPopWVal();
				this.EvalStackPop();
				this.EvalStackPush(evse);
				this.BIAddToList(baseoffset, line, (IRContainerType)thisTy);
			}
			else if(mns.Equals("list_make_space"))
			{
				this.BIListMakeSpace(baseoffset, line, (IRContainerType)thisTy);
				this.ReturnFromBuiltinClearTopKArgs(argc);
			}
			else if(mns.Equals("list_removeat"))
			{
				this.EvalStackPop();
				this.BIListRemoveUnknown(baseoffset, line, (IRContainerType)thisTy);
			}
			else if(mns.Equals("list_removeflags"))
			{
				if(!this.BICheckPtrArgNonNull(baseoffset + 1))
					this.SetInfeasable();
				else
				{
					this.EvalStackPush(GlobalAnalysisState.TProg.TypeTable.Int64Type, ZeroOne.Value.Unknown);
					this.SimulateArrayLoad(line, GlobalAnalysisState.TProg.TypeTable.BoolType);
					this.EvalStackPop();

					this.BIListRemoveUnknown(baseoffset, line, (IRContainerType)thisTy);
				}
			}
			else if(mns.Equals("list_reverse"))
			{
				this.BIPermuteListContents(baseoffset, line, (IRContainerType)thisTy);
			}
			else if(mns.Equals("list_sort_on"))
			{
				if(!this.BICheckPtrArgNonNull(baseoffset + 1))
					this.SetInfeasable();
				else
				{
					this.EvalStackPush(GlobalAnalysisState.TProg.TypeTable.Int64Type, ZeroOne.Value.Unknown);
					this.SimulateArrayLoad(line, GlobalAnalysisState.TProg.TypeTable.Int32Type);
					this.EvalStackPop();

					this.BIPermuteListContents(baseoffset, line, (IRContainerType)thisTy);
					this.EvalStackPop();
				}
			}
			else if(mns.Equals("list_getcount") || mns.Equals("hashset_getcount") || mns.Equals("dictionary_getcount"))
			{
				AContainer lo = (AContainer)this.BILoadUniqueEvalPtr(baseoffset);
				this.EvalStackPop();

				IRBasicAccessPath cbap = GlobalAnalysisState.TProg.GetAccessPathForSingleField(((IRContainerType)thisTy).CardField);
				lo.MarkLocationUsedModified(cbap, true, false, line);
				if(lo.IsKnownEmpty())
					this.EvalStackPush(GlobalAnalysisState.TProg.TypeTable.Int64Type, ZeroOne.Value.Zero);
				else
					this.EvalStackPush(GlobalAnalysisState.TProg.TypeTable.Int64Type, ZeroOne.Value.Unknown);
			}
			else if(mns.Equals("list_getitem"))
			{
				AContainer lo = (AContainer)this.BILoadUniqueEvalPtr(baseoffset);
				this.EvalStackPop();
				this.EvalStackPop();

				if(lo.IsKnownEmpty())
					this.SetInfeasable();
				else
				{
					IRBasicAccessPath cardbap = GlobalAnalysisState.TProg.GetAccessPathForSingleField(((IRContainerType)thisTy).CardField);
					lo.MarkLocationUsedModified(cardbap, true, false, line);

					IRBasicAccessPath contbap = GlobalAnalysisState.TProg.GetAccessPathForSingleField(((IRContainerType)thisTy).ContentsField);
					Nullable<APtrValueMap> pvm = lo.DoContainerContentsReadFromLocationBI(contbap, line);

					if(bd.ReturnType is IRNumericType)
						this.EvalStackPush((IRNumericType)bd.ReturnType, ZeroOne.Value.Unknown);
					else if(bd.ReturnType is IREnumType)
						this.EvalStackPush(((IREnumType)bd.ReturnType).UnerlyingNumericType, ZeroOne.Value.Unknown);
					else if(bd.ReturnType is IRPtrType)
						this.EvalStackPush((IRPtrType)bd.ReturnType, pvm.Value);
					else
						this.EvalStackPush((IRStructType)bd.ReturnType, pvm.Value);
				}
			}
			else if(mns.Equals("list_setitem"))
			{
				AEvalStackEntry evse = this.EvalStackPopWVal();
				this.EvalStackPop();
				this.EvalStackPush(evse);
				this.BIAddToList(baseoffset, line, (IRContainerType)thisTy);
			}
			else if(mns.Equals("hashset_gethvalid"))
			{
				AObject ll = this.BILoadUniqueEvalPtr(baseoffset);
				this.EvalStackPop();

				IRBasicAccessPath capp = GlobalAnalysisState.TProg.GetAccessPathForSingleField(((IRContainerType)thisTy).OptCapacityField);
				ll.MarkLocationUsedModified(capp, true, false, line);

				this.SimulateIndexAddrByField(((IRContainerType)thisTy).OptHashField, 0);
				this.SimulateDeRefIndirectRead(line);
			}
			else if(mns.Equals("hashset_getvalue"))
			{
				AContainer lo = (AContainer)this.BILoadUniqueEvalPtr(baseoffset);
				this.EvalStackPop();
				this.EvalStackPop();

				if(lo.IsKnownEmpty())
					this.SetInfeasable();
				else
				{
					IRBasicAccessPath cardbap = GlobalAnalysisState.TProg.GetAccessPathForSingleField(((IRContainerType)thisTy).OptCapacityField);
					lo.MarkLocationUsedModified(cardbap, true, false, line);

					IRBasicAccessPath contbap = GlobalAnalysisState.TProg.GetAccessPathForSingleField(((IRContainerType)thisTy).ContentsField);
					Nullable<APtrValueMap> pvm = lo.DoContainerContentsReadFromLocationBI(contbap, line);

					if(bd.ReturnType is IRNumericType)
						this.EvalStackPush((IRNumericType)bd.ReturnType, ZeroOne.Value.Unknown);
					else if(bd.ReturnType is IREnumType)
						this.EvalStackPush(((IREnumType)bd.ReturnType).UnerlyingNumericType, ZeroOne.Value.Unknown);
					else if(bd.ReturnType is IRPtrType)
						this.EvalStackPush((IRPtrType)bd.ReturnType, pvm.Value);
					else
						this.EvalStackPush((IRStructType)bd.ReturnType, pvm.Value);
				}
			}
			else if(mns.Equals("hashset_resizeasneeded"))
			{
				this.BIHashSetResize(baseoffset, line, (IRContainerType)thisTy);
				this.ReturnFromBuiltinClearTopKArgs(argc);
			}
			else if(mns.Equals("hashset_clear"))
			{
				this.BIClearSet(baseoffset, line, (IRContainerType)thisTy);
			}
			else if(mns.Equals("hashset_adddirect"))
			{
				this.BIAddToSetDirect(baseoffset, line, (IRContainerType)thisTy);
			}
			else if(mns.Equals("hashet_removeatdirect"))
			{
				this.EvalStackPop();
				this.BISetRemoveUnknown(baseoffset, line, (IRContainerType)thisTy);
			}
			else if(mns.Equals("hashet_removeatflags"))
			{
				if(!this.BICheckPtrArgNonNull(baseoffset + 1))
					this.SetInfeasable();
				else
				{
					this.EvalStackPush(GlobalAnalysisState.TProg.TypeTable.Int64Type, ZeroOne.Value.Unknown);
					this.SimulateArrayLoad(line, GlobalAnalysisState.TProg.TypeTable.BoolType);
					this.EvalStackPop();

					this.BISetRemoveUnknown(baseoffset, line, (IRContainerType)thisTy);
				}
			}
			else if(mns.Equals("get_key"))
			{
				this.SimulateIndexAddrByField(((IRKeyValuePairType)thisTy).KeyField, 0);
				this.SimulateDeRefIndirectRead(line);
			}
			else if(mns.Equals("get_value"))
			{
				this.SimulateIndexAddrByField(((IRKeyValuePairType)thisTy).ValueField, 0);
				this.SimulateDeRefIndirectRead(line);
			}
			else if(mns.Equals("dictionary_gethvalid"))
			{
				AObject ll = this.BILoadUniqueEvalPtr(baseoffset);
				this.EvalStackPop();

				IRBasicAccessPath capp = GlobalAnalysisState.TProg.GetAccessPathForSingleField(((IRDictionaryType)thisTy).OptCapacityField);
				ll.MarkLocationUsedModified(capp, true, false, line);

				this.SimulateIndexAddrByField(((IRDictionaryType)thisTy).OptHashField, 0);
				this.SimulateDeRefIndirectRead(line);
			}
			else if(mns.Equals("dictionary_getvalue"))
			{
				AContainer lo = (AContainer)this.BILoadUniqueEvalPtr(baseoffset);
				this.EvalStackPop();
				this.EvalStackPop();

				if(lo.IsKnownEmpty())
					this.SetInfeasable();
				else
				{
					IRBasicAccessPath cardbap = GlobalAnalysisState.TProg.GetAccessPathForSingleField(((IRDictionaryType)thisTy).OptCapacityField);
					lo.MarkLocationUsedModified(cardbap, true, false, line);

					IRBasicAccessPath contbap = GlobalAnalysisState.TProg.GetAccessPathForSingleField(((IRDictionaryType)thisTy).ContentsField);
					Nullable<APtrValueMap> pvm = lo.DoContainerContentsReadFromLocationBI(contbap, line);

					if(bd.ReturnType is IRNumericType)
						this.EvalStackPush((IRNumericType)bd.ReturnType, ZeroOne.Value.Unknown);
					else if(bd.ReturnType is IREnumType)
						this.EvalStackPush(((IREnumType)bd.ReturnType).UnerlyingNumericType, ZeroOne.Value.Unknown);
					else if(bd.ReturnType is IRPtrType)
						this.EvalStackPush((IRPtrType)bd.ReturnType, pvm.Value);
					else
						this.EvalStackPush((IRStructType)bd.ReturnType, pvm.Value);
				}
			}
			else if(mns.Equals("dictionary_resizeasneeded"))
			{
				this.BIDictionaryResize(baseoffset, line, (IRDictionaryType)thisTy);
				this.ReturnFromBuiltinClearTopKArgs(argc);
			}
			else if(mns.Equals("dictionary_clear"))
			{
				this.BIClearDictionary(baseoffset, line, (IRDictionaryType)thisTy);
			}
			else if(mns.Equals("dictionary_adddirect"))
			{
				this.BIAddToDictionaryDirect(baseoffset, line, (IRDictionaryType)thisTy);
			}
			else if(mns.Equals("dictionary_removeatdirect"))
			{
				this.EvalStackPop();
				this.BIDictionaryRemoveUnknown(baseoffset, line, (IRDictionaryType)thisTy);
			}
			else if(mns.Equals("valuetype_equals"))
			{
				APtrValueMap ppt = this.EvalStackPopWVal().PointerValue;
				for(int i = 0; i < ppt.PTargetCount; ++i)
					((AObject)this.ResolvePointerTarget(ppt.PTargets[i])).MarkLocationAllFieldsUsedBI(line);

				AObject tl = this.BILoadUniqueEvalPtr(baseoffset);
				tl.MarkLocationAllFieldsUsedBI(line);
				this.EvalStackPop();

				this.EvalStackPush(GlobalAnalysisState.TProg.TypeTable.Int64Type, ZeroOne.Value.Unknown);
			}
			else if(mns.Equals("valuetype_hashcode"))
			{
				this.SimulateDeRefIndirectRead(line);
				this.EvalStackPop();
				this.EvalStackPush(GlobalAnalysisState.TProg.TypeTable.Int64Type, ZeroOne.Value.Unknown);
			}
			else if(mns.Equals("valuetype_equals_static"))
			{
				this.EvalStackPop();
				this.EvalStackPop();
				this.EvalStackPush(GlobalAnalysisState.TProg.TypeTable.Int64Type, ZeroOne.Value.Unknown);
			}
			else if(mns.Equals("valuetype_hashcode_static"))
			{
				this.EvalStackPop();
				this.EvalStackPush(GlobalAnalysisState.TProg.TypeTable.Int64Type, ZeroOne.Value.Unknown);
			}
			else if(mns.Equals("valuetype_tostring"))
			{
				this.SimulateDeRefIndirectRead(line);
				this.EvalStackPop();
				this.SimulatePushString(line);
			}
			else if(mns.Equals("enum_compareto"))
			{
				APtrValueMap ppt = this.EvalStackPopWVal().PointerValue;
				for(int i = 0; i < ppt.PTargetCount; ++i)
					((AObject)this.ResolvePointerTarget(ppt.PTargets[i])).MarkLocationAllFieldsUsedBI(line);

				AObject tl = this.BILoadUniqueEvalPtr(baseoffset);
				tl.MarkLocationAllFieldsUsedBI(line);
				this.EvalStackPop();

				this.EvalStackPush(GlobalAnalysisState.TProg.TypeTable.Int64Type, ZeroOne.Value.Unknown);
			}
			else if(mns.Equals("datetime_to_universal"))
			{
				this.SimulateDeRefIndirectRead(line);
				this.EvalStackPop();
				this.SimulateAllocBlank(thisTy, line); //only has numeric fields so no other init needed.
			}
			else if(mns.Equals("datetime_to_local"))
			{
				this.SimulateDeRefIndirectRead(line);
				this.EvalStackPop();
				this.SimulateAllocBlank(thisTy, line); //only has numeric fields so no other init needed.
			}
			else if(mns.Equals("datetime_now"))
			{
				this.SimulateAllocBlank(thisTy, line); //only has numeric fields so no other init needed.

				this.BIHavocExternalState(line);
			}
			else if(mns.Equals("datetime_tofileutc"))
			{
				this.SimulateDeRefIndirectRead(line);
				this.EvalStackPop();
				this.EvalStackPush(GlobalAnalysisState.TProg.TypeTable.Int64Type, ZeroOne.Value.Unknown);
			}
			else if(mns.Equals("datetime_internalkind"))
			{
				this.SimulateDeRefIndirectRead(line);
				this.EvalStackPop();
				this.EvalStackPush(GlobalAnalysisState.TProg.TypeTable.UInt64Type, ZeroOne.Value.Unknown);
			}
			else if(mns.Equals("filestream_close"))
			{
				AObject fso = this.BILoadUniqueEvalPtr(baseoffset);
				IRMemberField statef = fso.LocationType.TypeDescription.GetFieldWithNameDefIn("state");
				IRBasicAccessPath fsp = GlobalAnalysisState.TProg.GetAccessPathForSingleField(statef);
				fso.MarkLocationUsedModified(fsp, true, true, line);

				this.ReturnFromBuiltinClearTopKArgs(argc);
				this.BIHavocExternalState(line);
			}
			else if(mns.Equals("filestream_read"))
			{
				if(!this.BICheckPtrArgNonNull(baseoffset + 1))
					this.SetInfeasable();
				else
				{
					this.EvalStackPop();
					this.EvalStackPop();

					AObject fso = this.BILoadUniqueEvalPtr(baseoffset);
					IRMemberField statef = fso.LocationType.TypeDescription.GetFieldWithNameDefIn("state");
					IRBasicAccessPath fsp = GlobalAnalysisState.TProg.GetAccessPathForSingleField(statef);
					fso.MarkLocationUsedModified(fsp, true, true, line);

					this.EvalStackPush(GlobalAnalysisState.TProg.TypeTable.Int64Type, ZeroOne.Value.Unknown);
					this.EvalStackPush(GlobalAnalysisState.TProg.TypeTable.UInt8Type, ZeroOne.Value.Unknown);
					this.SimulateArrayStore(line, GlobalAnalysisState.TProg.TypeTable.UInt8Type);

					this.EvalStackPop();
					this.BIHavocExternalState(line);

					this.EvalStackPush(GlobalAnalysisState.TProg.TypeTable.Int64Type, ZeroOne.Value.Unknown);
				}
			}
			else if(mns.Equals("filestream_seek"))
			{
				AObject fso = this.BILoadUniqueEvalPtr(baseoffset);
				IRMemberField statef = fso.LocationType.TypeDescription.GetFieldWithNameDefIn("state");
				IRBasicAccessPath fsp = GlobalAnalysisState.TProg.GetAccessPathForSingleField(statef);
				fso.MarkLocationUsedModified(fsp, true, true, line);

				this.ReturnFromBuiltinClearTopKArgs(argc);
				this.BIHavocExternalState(line);

				this.EvalStackPush(GlobalAnalysisState.TProg.TypeTable.Int64Type, ZeroOne.Value.Unknown);
			}
			else if(mns.Equals("filestream_write"))
			{
				if(!this.BICheckPtrArgNonNull(baseoffset + 1))
					this.SetInfeasable();
				else
				{
					this.EvalStackPop();
					this.EvalStackPop();

					AObject fso = this.BILoadUniqueEvalPtr(baseoffset);
					IRMemberField statef = fso.LocationType.TypeDescription.GetFieldWithNameDefIn("state");
					IRBasicAccessPath fsp = GlobalAnalysisState.TProg.GetAccessPathForSingleField(statef);
					fso.MarkLocationUsedModified(fsp, true, true, line);

					this.EvalStackPush(GlobalAnalysisState.TProg.TypeTable.Int64Type, ZeroOne.Value.Unknown);
					this.SimulateArrayLoad(line, GlobalAnalysisState.TProg.TypeTable.UInt8Type);

					this.EvalStackPop();
					this.EvalStackPop();
					this.BIHavocExternalState(line);
				}
			}
			else if(mns.Equals("filestream_length"))
			{
				AObject fso = this.BILoadUniqueEvalPtr(baseoffset);
				IRMemberField statef = fso.LocationType.TypeDescription.GetFieldWithNameDefIn("state");
				IRBasicAccessPath fsp = GlobalAnalysisState.TProg.GetAccessPathForSingleField(statef);
				fso.MarkLocationUsedModified(fsp, true, false, line);

				this.ReturnFromBuiltinClearTopKArgs(argc);
				this.BIHavocExternalState(line);

				this.EvalStackPush(GlobalAnalysisState.TProg.TypeTable.Int64Type, ZeroOne.Value.Unknown);
			}
			else if(mns.Equals("stdin_init"))
			{
				this.BIHavocExternalState(line);
			}
			else if(mns.Equals("stdout_init"))
			{
				this.BIHavocExternalState(line);
			}
			else if(mns.Equals("stdin_readchar"))
			{
				AObject oo = this.BILoadUniqueEvalPtr(baseoffset);
				IRMemberField statef = thisTy.TypeDescription.GetFieldWithNameDefIn("state");
				IRBasicAccessPath statebap = GlobalAnalysisState.TProg.GetAccessPathForSingleField(statef);
				oo.MarkLocationUsedModified(statebap, true, true, line);

				this.EvalStackPop();
				this.BIHavocExternalState(line);

				this.EvalStackPush(GlobalAnalysisState.TProg.TypeTable.Int32Type, ZeroOne.Value.Unknown);
			}
			else if(mns.Equals("stdout_writechar"))
			{
				AObject oo = this.BILoadUniqueEvalPtr(baseoffset);
				IRMemberField statef = thisTy.TypeDescription.GetFieldWithNameDefIn("state");
				IRBasicAccessPath statebap = GlobalAnalysisState.TProg.GetAccessPathForSingleField(statef);
				oo.MarkLocationUsedModified(statebap, true, true, line);

				this.EvalStackPop();
				this.EvalStackPop();
				this.BIHavocExternalState(line);
			}
			else if(mns.Equals("file_copy"))
			{
				this.BIReadStringData(baseoffset, line);
				this.BIReadStringData(baseoffset + 1, line);

				this.BIHavocExternalState(line);
				this.ReturnFromBuiltinClearTopKArgs(argc);
			}
			else if(mns.Equals("file_delete"))
			{
				this.BIReadStringData(baseoffset, line);

				this.BIHavocExternalState(line);
				this.ReturnFromBuiltinClearTopKArgs(argc);
			}
			else if(mns.Equals("file_exists"))
			{
				this.BIReadStringData(baseoffset, line);
				this.EvalStackPop();

				this.EvalStackPush(GlobalAnalysisState.TProg.TypeTable.BoolType, ZeroOne.Value.Unknown);
				this.BIHavocExternalState(line);
			}
			else if(mns.Equals("file_move"))
			{
				this.BIReadStringData(baseoffset, line);
				this.BIReadStringData(baseoffset + 1, line);

				this.BIHavocExternalState(line);
				this.ReturnFromBuiltinClearTopKArgs(argc);
			}
			else if(mns.Equals("fsaccess_getinfo"))
			{
				this.BIReadStringData(baseoffset, line);
				this.EvalStackPop();
				this.SimulateAllocBlank(thisTy, line); //allocate a FSAccessInfo object which only has scalar fields

				this.BIHavocExternalState(line);
			}
			else if(mns.Equals("fsaccess_setinfo"))
			{
				this.BIReadStringData(baseoffset, line);
				APtrValueMap ppta = this.EvalStackPeek().PointerValue;
				for(int i = 0; i < ppta.PTargetCount; ++i)
					this.ResolvePointerTarget(ppta.PTargets[i]).MarkLocationAllFieldsUsedBI(line);

				this.BIHavocExternalState(line);
				this.ReturnFromBuiltinClearTopKArgs(argc);
			}
			else if(mns.Equals("directory_create"))
			{
				this.BIReadStringData(baseoffset, line);
				this.EvalStackPop();

				this.BIHavocExternalState(line);
			}
			else if(mns.Equals("directory_delete"))
			{
				this.BIReadStringData(baseoffset, line);

				this.BIHavocExternalState(line);
				this.ReturnFromBuiltinClearTopKArgs(argc);
			}
			else if(mns.Equals("directory_getfilesordirs"))
			{
				this.BIReadStringData(baseoffset, line);
				this.BIReadStringData(baseoffset + 1, line);

				this.BIHavocExternalState(line);
				this.ReturnFromBuiltinClearTopKArgs(argc);

				AObject sa = this.AllocateStringArray(line);
				APossiblePointerTarget ap = new APossiblePointerTarget(sa.Address);
				this.EvalStackPush(GlobalAnalysisState.TProg.TypeTable.LookupPointerTypeFor((IRClassType)sa.LocationType), ap, true);
			}
			else if(mns.Equals("directory_exists"))
			{
				this.BIReadStringData(baseoffset, line);
				this.EvalStackPop();

				this.EvalStackPush(GlobalAnalysisState.TProg.TypeTable.BoolType, ZeroOne.Value.Unknown);
				this.BIHavocExternalState(line);
			}
			else if(mns.Equals("directory_current"))
			{
				this.BIReadStringData(baseoffset, line);
				this.EvalStackPop();
				this.SimulatePushString(line);

				this.BIHavocExternalState(line);
			}
			else if(mns.Equals("directory_move"))
			{
				this.BIReadStringData(baseoffset, line);
				this.BIReadStringData(baseoffset + 1, line);

				this.BIHavocExternalState(line);
				this.ReturnFromBuiltinClearTopKArgs(argc);
			}
			else if(mns.Equals("path_normalize"))
			{
				this.BIReadStringData(baseoffset, line);
				this.ReturnFromBuiltinClearTopKArgs(argc);
				this.SimulatePushString(line);
			}
			else if(mns.Equals("binaryconv_fromdouble"))
			{
				this.EvalStackPop();
				this.EvalStackPush(GlobalAnalysisState.TProg.TypeTable.UInt64Type, ZeroOne.Value.Unknown);
			}
			else if(mns.Equals("binaryconv_fromfloat"))
			{
				this.EvalStackPop();
				this.EvalStackPush(GlobalAnalysisState.TProg.TypeTable.UInt32Type, ZeroOne.Value.Unknown);
			}
			else if(mns.Equals("binaryconv_todouble"))
			{
				this.EvalStackPop();
				this.EvalStackPush(GlobalAnalysisState.TProg.TypeTable.Float64Type, ZeroOne.Value.Unknown);
			}
			else if(mns.Equals("binaryconv_tofloat"))
			{
				this.EvalStackPop();
				this.EvalStackPush(GlobalAnalysisState.TProg.TypeTable.Float32Type, ZeroOne.Value.Unknown);
			}
			else if(mns.Equals("monitor_exit"))
			{
				this.EvalStackPop();
			}
			else if(mns.Equals("monitor_enter"))
			{
				this.EvalStackPop();
			}
			else
				DebugReport.ReportError("Unknown Builtin Method: " + mns);
		}

		/// <summary>
		/// Get the unique object that a pointer refers to (or null).
		/// </summary>
		private AObject BILoadUniqueEvalPtr(int pos)
		{
			APtrValueMap ppa = this.m_evalstack[pos].PointerValue;
			if(ppa.PTargetCount == 0)
				return null;
			else
				return this.ResolvePointerTarget(ppa.PTargets[0]);
		}

		/// <summary>
		/// Return true if the pointer arg at pos is not known to be null.
		/// </summary>
		private bool BICheckPtrArgNonNull(int pos)
		{
			APtrValueMap ppa = this.m_evalstack[pos].PointerValue;
			return ppa.PTargetCount != 0;
		}

		/// <summary>
		/// Mark reading from the string with the pointer at the given position (allows possibly multiple targets).
		/// </summary>
		private void BIReadStringData(int pos, int line)
		{
			IRMemberField slf = GlobalAnalysisState.TProg.TypeTable.StringObjectType.TypeDescription.GetFieldWithNameDefIn("slen");
			IRBasicAccessPath slfp = GlobalAnalysisState.TProg.GetAccessPathForSingleField(slf);
			IRMemberField svf = GlobalAnalysisState.TProg.TypeTable.StringObjectType.TypeDescription.GetFieldWithNameDefIn("sval");
			IRBasicAccessPath svfp = GlobalAnalysisState.TProg.GetAccessPathForSingleField(svf);

			APtrValueMap appa = this.m_evalstack[pos].PointerValue;
			for(int i = 0; i < appa.PTargetCount; ++i)
			{
				AObject so = this.ResolvePointerTarget(appa.PTargets[i]);
				so.DoGeneralReadFromLocation(slfp, line);
				so.DoGeneralReadFromLocation(svfp, line);
			}
		}

		private void BISimulateCons_Default(bool conscall)
		{
			if(!conscall)
				this.EvalStackPop();
		}

		private void BISimulateCons_KeyValuePair(IRType thisTy, int line)
		{
			AEvalStackEntry val = this.EvalStackPopWVal();
			AEvalStackEntry key = this.EvalStackPopWVal();
			IRKeyValuePairType kvpty = (IRKeyValuePairType)thisTy;

			this.SimulateDup();
			this.SimulateIndexAddrByField(((IRKeyValuePairType)thisTy).ValueField, 0);
			this.EvalStackPush(val);
			this.SimulateDeRefIndirectWrite(line);

			this.SimulateDup();
			this.SimulateIndexAddrByField(((IRKeyValuePairType)thisTy).KeyField, 0);
			this.EvalStackPush(key);
			this.SimulateDeRefIndirectWrite(line);

			this.SimulateDeRefIndirectRead(line);
		}

		/// <summary>
		/// Write to the global filesytem value.
		/// </summary>
		private void BIHavocExternalState(int line)
		{
			IRClassType cty = (IRClassType)GlobalAnalysisState.TProg.TypeTable.LookupTypeForName("System.ExternalState");
			IRStaticField sfd = GlobalAnalysisState.TProg.NameTable.LookupStaticField(cty, "fsstate");

			AHomeLocation fshl = this.ResolveLocalGlobalTarget(sfd);
			fshl.ReadNumericFromViaName(line);
			fshl.WriteNumericToViaName(ZeroOne.Value.Unknown, line);
		}

		private void BIAddToList(int basepos, int line, IRContainerType listtype)
		{
			AContainer lo = (AContainer)this.BILoadUniqueEvalPtr(basepos);
			AEvalStackEntry addinfo = this.EvalStackPopWVal();
			this.EvalStackPop();

			IRBasicAccessPath cardbap = GlobalAnalysisState.TProg.GetAccessPathForSingleField(listtype.CardField);
			lo.MarkLocationUsedModified(cardbap, true, true, line);

			IRBasicAccessPath contbap = GlobalAnalysisState.TProg.GetAccessPathForSingleField(listtype.ContentsField);
			if(addinfo.SLocType is IRNumericType || addinfo.SLocType is IREnumType)
				lo.DoContainerContentsWriteToLocationBI(contbap, default(APtrValueMap), line, null);
			else if(addinfo.SLocType is IRPtrType)
				lo.DoContainerContentsWriteToLocationBI(contbap, addinfo.PointerValue, line, null);
			else
				lo.DoContainerContentsWriteToLocationBI(contbap, addinfo.StructValue, line, null);
		}

		private void BIClearList(int basepos, int line, IRContainerType listtype)
		{
			AContainer lo = (AContainer)this.BILoadUniqueEvalPtr(basepos);
			this.EvalStackPop();
			
			IRBasicAccessPath cardbap = GlobalAnalysisState.TProg.GetAccessPathForSingleField(listtype.CardField);
			lo.MarkLocationUsedModified(cardbap, true, true, line);

			IRBasicAccessPath contbap = GlobalAnalysisState.TProg.GetAccessPathForSingleField(listtype.ContentsField);
			lo.DoContainerContentsClearBI(contbap, line);
		}

		private void BIListMakeSpace(int basepos, int line, IRContainerType listtype)
		{
			AContainer lo = (AContainer)this.BILoadUniqueEvalPtr(basepos);
			this.EvalStackPop();

			IRBasicAccessPath cardbap = GlobalAnalysisState.TProg.GetAccessPathForSingleField(listtype.CardField);
			lo.MarkLocationUsedModified(cardbap, true, true, line);

			lo.MarkLocationAllFieldsUsedBI(line);

			IRBasicAccessPath contbap = GlobalAnalysisState.TProg.GetAccessPathForSingleField(listtype.ContentsField);
			lo.DoContainerContentsReorgBI(contbap, line);
		}

		private void BIPermuteListContents(int basepos, int line, IRContainerType listtype)
		{
			AContainer ll = (AContainer)this.BILoadUniqueEvalPtr(basepos);

			IRBasicAccessPath cardbap = GlobalAnalysisState.TProg.GetAccessPathForSingleField(listtype.CardField);
			ll.MarkLocationUsedModified(cardbap, true, false, line);

			ll.MarkLocationAllFieldsUsedBI(line);

			IRBasicAccessPath contbap = GlobalAnalysisState.TProg.GetAccessPathForSingleField(listtype.ContentsField);
			ll.DoContainerContentsReorgBI(contbap, line);
		}

		private void BIListRemoveUnknown(int basepos, int line, IRContainerType listtype)
		{
			AContainer lo = (AContainer)this.BILoadUniqueEvalPtr(basepos);
			this.EvalStackPop();
			
			IRBasicAccessPath cardbap = GlobalAnalysisState.TProg.GetAccessPathForSingleField(listtype.CardField);
			lo.MarkLocationUsedModified(cardbap, true, true, line);

			lo.MarkLocationAllFieldsUsedBI(line);

			IRBasicAccessPath contbap = GlobalAnalysisState.TProg.GetAccessPathForSingleField(listtype.ContentsField);
			lo.DoContainerContentsRemoveBI(contbap, line);
		}

		private void BIHashSetResize(int basepos, int line, IRContainerType settype)
		{
			AContainer ll = (AContainer)this.BILoadUniqueEvalPtr(basepos);

			IRBasicAccessPath cardbap = GlobalAnalysisState.TProg.GetAccessPathForSingleField(settype.CardField);
			ll.MarkLocationUsedModified(cardbap, true, false, line);

			IRBasicAccessPath capbap = GlobalAnalysisState.TProg.GetAccessPathForSingleField(settype.OptCapacityField);
			ll.MarkLocationUsedModified(capbap, true, true, line);

			IRBasicAccessPath hashbap = GlobalAnalysisState.TProg.GetAccessPathForSingleField(settype.OptHashField);
			ll.MarkLocationUsedModified(hashbap, true, true, line);

			ll.MarkLocationAllFieldsUsedBI(line);

			IRBasicAccessPath contbap = GlobalAnalysisState.TProg.GetAccessPathForSingleField(settype.ContentsField);
			ll.DoContainerContentsReorgBI(contbap, line);
		}

		private void BIAddToSetDirect(int basepos, int line, IRContainerType settype)
		{
			AContainer lo = (AContainer)this.BILoadUniqueEvalPtr(basepos);
			AEvalStackEntry addinfo = this.EvalStackPopWVal();
			this.EvalStackPop();
			this.EvalStackPop();
			this.EvalStackPop();

			IRBasicAccessPath cardbap = GlobalAnalysisState.TProg.GetAccessPathForSingleField(settype.CardField);
			lo.MarkLocationUsedModified(cardbap, true, true, line);

			IRBasicAccessPath capbap = GlobalAnalysisState.TProg.GetAccessPathForSingleField(settype.OptCapacityField);
			lo.MarkLocationUsedModified(capbap, true, false, line);

			IRBasicAccessPath hashbap = GlobalAnalysisState.TProg.GetAccessPathForSingleField(settype.OptHashField);
			lo.MarkLocationUsedModified(hashbap, false, true, line);

			IRBasicAccessPath contbap = GlobalAnalysisState.TProg.GetAccessPathForSingleField(settype.ContentsField);
			if(addinfo.SLocType is IRNumericType || addinfo.SLocType is IREnumType)
				lo.DoContainerContentsWriteToLocationBI(contbap, default(APtrValueMap), line, null);
			else if(addinfo.SLocType is IRPtrType)
				lo.DoContainerContentsWriteToLocationBI(contbap, addinfo.PointerValue, line, settype.ContentsField);
			else
				lo.DoContainerContentsWriteToLocationBI(contbap, addinfo.StructValue, line, null);
		}

		private void BIClearSet(int basepos, int line, IRContainerType settype)
		{
			AContainer lo = (AContainer)this.BILoadUniqueEvalPtr(basepos);
			this.EvalStackPop();

			IRBasicAccessPath cardbap = GlobalAnalysisState.TProg.GetAccessPathForSingleField(settype.CardField);
			lo.MarkLocationUsedModified(cardbap, false, true, line);

			IRBasicAccessPath capbap = GlobalAnalysisState.TProg.GetAccessPathForSingleField(settype.OptCapacityField);
			lo.MarkLocationUsedModified(capbap, true, false, line);

			IRBasicAccessPath hashbap = GlobalAnalysisState.TProg.GetAccessPathForSingleField(settype.OptHashField);
			lo.MarkLocationUsedModified(hashbap, true, true, line);

			IRBasicAccessPath contbap = GlobalAnalysisState.TProg.GetAccessPathForSingleField(settype.ContentsField);
			lo.DoContainerContentsClearBI(contbap, line);
		}

		private void BISetRemoveUnknown(int basepos, int line, IRContainerType settype)
		{
			AContainer lo = (AContainer)this.BILoadUniqueEvalPtr(basepos);
			this.EvalStackPop();

			IRBasicAccessPath cardbap = GlobalAnalysisState.TProg.GetAccessPathForSingleField(settype.CardField);
			lo.MarkLocationUsedModified(cardbap, true, true, line);

			IRBasicAccessPath capbap = GlobalAnalysisState.TProg.GetAccessPathForSingleField(settype.OptCapacityField);
			lo.MarkLocationUsedModified(capbap, true, false, line);

			IRBasicAccessPath hashbap = GlobalAnalysisState.TProg.GetAccessPathForSingleField(settype.OptHashField);
			lo.MarkLocationUsedModified(hashbap, false, true, line);

			IRBasicAccessPath contbap = GlobalAnalysisState.TProg.GetAccessPathForSingleField(settype.ContentsField);
			lo.DoContainerContentsRemoveBI(contbap, line);
		}

		private void BIDictionaryResize(int basepos, int line, IRDictionaryType dicttype)
		{
			AContainer ll = (AContainer)this.BILoadUniqueEvalPtr(basepos);

			IRBasicAccessPath cardbap = GlobalAnalysisState.TProg.GetAccessPathForSingleField(dicttype.CardField);
			ll.MarkLocationUsedModified(cardbap, true, false, line);

			IRBasicAccessPath capbap = GlobalAnalysisState.TProg.GetAccessPathForSingleField(dicttype.OptCapacityField);
			ll.MarkLocationUsedModified(capbap, true, true, line);

			IRBasicAccessPath hashbap = GlobalAnalysisState.TProg.GetAccessPathForSingleField(dicttype.OptHashField);
			ll.MarkLocationUsedModified(hashbap, true, true, line);

			ll.MarkLocationAllFieldsUsedBI(line);

			IRBasicAccessPath contbap = GlobalAnalysisState.TProg.GetAccessPathForSingleField(dicttype.ContentsField);
			ll.DoContainerContentsReorgBI(contbap, line);
		}

		private void BIAddToDictionaryDirect(int basepos, int line, IRDictionaryType dicttype)
		{
			AContainer lo = (AContainer)this.BILoadUniqueEvalPtr(basepos);
			AEvalStackEntry addinfo = this.EvalStackPopWVal();
			this.EvalStackPop();
			this.EvalStackPop();
			this.EvalStackPop();

			IRBasicAccessPath cardbap = GlobalAnalysisState.TProg.GetAccessPathForSingleField(dicttype.CardField);
			lo.MarkLocationUsedModified(cardbap, true, true, line);

			IRBasicAccessPath capbap = GlobalAnalysisState.TProg.GetAccessPathForSingleField(dicttype.OptCapacityField);
			lo.MarkLocationUsedModified(capbap, true, false, line);

			IRBasicAccessPath hashbap = GlobalAnalysisState.TProg.GetAccessPathForSingleField(dicttype.OptHashField);
			lo.MarkLocationUsedModified(hashbap, false, true, line);

			IRBasicAccessPath contbap = GlobalAnalysisState.TProg.GetAccessPathForSingleField(dicttype.ContentsField);
			IRMemberField keyf = ((IRKeyValuePairType)dicttype.ContainerContentsType).KeyField;
			lo.DoContainerContentsWriteToLocationBI(contbap, addinfo.StructValue, line, (keyf.FieldType is IRPtrType ? keyf : null));
		}

		private void BIClearDictionary(int basepos, int line, IRDictionaryType dicttype)
		{
			AContainer lo = (AContainer)this.BILoadUniqueEvalPtr(basepos);
			this.EvalStackPop();

			IRBasicAccessPath cardbap = GlobalAnalysisState.TProg.GetAccessPathForSingleField(dicttype.CardField);
			lo.MarkLocationUsedModified(cardbap, false, true, line);

			IRBasicAccessPath capbap = GlobalAnalysisState.TProg.GetAccessPathForSingleField(dicttype.OptCapacityField);
			lo.MarkLocationUsedModified(capbap, true, false, line);

			IRBasicAccessPath hashbap = GlobalAnalysisState.TProg.GetAccessPathForSingleField(dicttype.OptHashField);
			lo.MarkLocationUsedModified(hashbap, true, true, line);

			IRBasicAccessPath contbap = GlobalAnalysisState.TProg.GetAccessPathForSingleField(dicttype.ContentsField);
			lo.DoContainerContentsClearBI(contbap, line);
		}

		private void BIDictionaryRemoveUnknown(int basepos, int line, IRDictionaryType dicttype)
		{
			AContainer lo = (AContainer)this.BILoadUniqueEvalPtr(basepos);
			this.EvalStackPop();

			IRBasicAccessPath cardbap = GlobalAnalysisState.TProg.GetAccessPathForSingleField(dicttype.CardField);
			lo.MarkLocationUsedModified(cardbap, true, true, line);

			IRBasicAccessPath capbap = GlobalAnalysisState.TProg.GetAccessPathForSingleField(dicttype.OptCapacityField);
			lo.MarkLocationUsedModified(capbap, true, false, line);

			IRBasicAccessPath hashbap = GlobalAnalysisState.TProg.GetAccessPathForSingleField(dicttype.OptHashField);
			lo.MarkLocationUsedModified(hashbap, false, true, line);

			IRBasicAccessPath contbap = GlobalAnalysisState.TProg.GetAccessPathForSingleField(dicttype.ContentsField);
			lo.DoContainerContentsRemoveBI(contbap, line);
		}
	}
}
